var QS_MessageManagement = null;

Role('QS.Message.DBHelper',{
	methods:{
		dataAccess: function(parameter, callback){
			if (typeof(callback) == 'undefined') {
				callback = {};
			}
			if (typeof(callback["args"])== 'undefined') {
				callback["args"] = {};
			}
			
			//DBHelper.MessageDateInterface
			var self = this;					
			DBHelper.getMessageList(parameter, function(o){
				callback["args"]["rtnValue"] = o;
				self.callCallBack(callback);
			});
		},
		callCallBack: function(callback){
			if (typeof(callback["callee"]) == 'function') {
				callback["callee"].call(callback["caller"], callback["args"]);
			}
		},
		attatchRtnValue:function(callback, rtnValue){
			if (typeof(callback['args']) == 'undefined') {
				callback['args'] = Joose.I.Object;
			}
			callback['args']["rtnValue"] = rtnValue;
		}
	}
});

Class('QS.Message.MessageItem',{
	does:[QS.Message.DBHelper],
	has: {
		messageId: null,
		senderAddress: null,
		receiverAddress: null,
		messageType:null,
		memberType:null,
		subject: null,
		content: null,
		createTime: null,
		attachment: null,
		messageStatus: null
	},
	
	body: function(){
//		console.log('QS.Message.MessageItem body function invoked.');
	},
	
	my:{
		has:{
				opened:{is:'rw',init:Joose.I.Object}
		},
		methods:{
			openInNewWindow: function(item){
				if(this.opened[item.messageId] || this.opened[item.messageId] === true) return;
				var scrollPannel,self = this;
				var win = new Util.RtqWindow(document.body, {
					windowReady: function(obj){
						var el = $('<div class="qs-message-viewer">' +
							'<div class="hd">' +
                                '<div class="row clearfix"><strong>From: </strong><span class="from"></span></div>'+		
								'<div class="row clearfix"><strong>To: </strong><span class="to"></span></div>'+
								'<div class="row clearfix"><strong>Subject: </strong><span class="subject"></span></div>'+					
							    /*
								'<table style="width:400px;">'+
								'<tr><td class="label" width="55"><strong>From: </strong></td><td class="from"></td><tr>' +
								'<tr><td class="label" width="55"><strong>To: </strong></td><td class="to"></td><tr>' +
								'<tr><td valign="top" class="label" width="55"><strong>Subject: </strong></td><td class="subject"></td><tr>' +
								'</table>'+*/
							'</div>' +
							'<div class="content"><pre></pre></div>' +
						'</div>');
						el.appendTo(obj.contentEl);
						
						el.find('.from').html("" + item['senderAddress']);
						el.find('.to').html("" + item['receiverAddress'].replace(/,/g, ', '));
						el.find('.subject').text(item['subject']);
						el.find('.content pre').text(item['content']);
						scrollPannel = new Util.ScrollPanel(el.find('.content pre'));
						
						obj.el.find('.win-hd h3 span').css({
							'width': '100%',
							'margin-left': '-50px',
							'text-indent': '50px'
						});
                        el.find('.row span').css({'width': obj.contentEl.width() - el.find('strong').outerWidth(true)-10});
						var h = obj.contentEl.height() - obj.contentEl.find('.hd').outerHeight(true);
						scrollPannel.reSize(obj.cfg.width, h);
					},
					beforeClosed: function(){
							self.opened[item.messageId] = false;
					},
					onResized: function(obj, w, h){
						var el = obj.contentEl;
						el.find('.row span').css({'width': w - el.find('strong').outerWidth(true)-10});
						var h = el.height() - el.find('.hd').outerHeight(true);
						scrollPannel.reSize(obj.cfg.width, h);
					}
				}, {
					title: item['subject'],
					oldBox: {
						width: 400,
						height: 400
					},
					width: 400,
					minWidth: 250,
					height: 400,
					minHeight: 300,
					resizable: true,
					isGlobal: true,
					hasSettingPanel: false
				});
				
				win.titleEl.find('h3 span').html(item['subject']);
				rtqWindowGroup.register(win);
				this.opened[item.messageId] = true;
			}
		}
	},
	
	methods: {
		initialize:function(){
//			console.log(this);
		},
		read: function(callback){
			this.dataAccess({
				module: this.messageStatus == 0 ? 'readandupdate' : 'read',
				messageId: this.messageId,
				mailType: this.memberType
			}, {
				caller:this,
				callee:this.readCallBack,
				args: {
					callback: callback
				}
			});
		},
		readCallBack: function(args){
			var o = args["rtnValue"]||{}
			o = $.evalJSON(o);
			this.content = o["content"];
			this.messageStatus = o["messageStatus"];
			this.attachment = o["attachment"];
			this.senderAddress = o["senderAddress"];
			this.receiverAddress = o["receiverAddress"];
			this.messageType = o["messageType"];
			this.subject = o["subject"];
			this.createTime = o["createTime"];
			
			if (typeof(args['callback']) != 'undefined') {
				this.attatchRtnValue(args['callback'],this);
				this.callCallBack(args['callback']);
			}
		},
		remove: function(callback){
			this.dataAccess({
				module: 'delete',
	            messageId: this.messageId,
				mailType: this.memberType
			}, {
				caller:this,
				callee:this.removeCallBack,
				args: {
					callback: callback
				}
			});
		},
		removeCallBack:function(args){
			//
			
			if (typeof(args['callback']) != 'undefined') {
				this.attatchRtnValue(args['callback'],this);
				this.callCallBack(args['callback']);
			}
			delete this;
		}
	}
});

Role('QS.Message.IComponet',{
	has:{
		management:{is:'r'}
	}
});

Class('QS.Message.DataManager',{
	does:[QS.Message.DBHelper, QS.Message.IComponet],
	has: {
		receivedList:{is:'rw',init:Joose.I.Object},
		sentList:{is:'rw',init:Joose.I.Object},
		pagingList:{is:'rw',init:Joose.I.Object}
	},
	
	body:function(){
//		console.log('QS.Message.DataManager body function invoked.');
	},
	
	methods: {
		initialize:function(){
			var pagingPara = {
				pageSize: 20,
				pageNo: 1,
				sortField: 1, // sortField  0:from, 1:received, 2:subject, 3:messageType;
				sortType: 2 //1:asc, 2:desc ,received should be desc
			};
			
			this.loadReceived(pagingPara,{
				caller: this.getManagement(),
				callee: this.getManagement().loadListCallBack,
				args: pagingPara
			});
		},
		
		load:function(args, callback, loadCallBack){
			this.dataAccess({
				module: 'getmessagelist',
				mailType: args['mailType'], //0 inbox, 1 outbox
				pageSize: args['pageSize'],
				pageNo: args['pageNo'],
				sortField: args['sortField'], // sortField  0:from, 1:received, 2:subject, 3:messageType;
				sortType: args['sortType'] //sortType 1:asc, 2:desc
			}, {
				caller: this,
				callee: loadCallBack,
				args: {
					callback: callback
				}
			});
		},
		loadReceived: function(args, callback){
			args["mailType"] = '0';
			this.load(args, callback, this.loadReceivedCallBack);
		},
		loadSent: function(args, callback){
			args["mailType"] = '1';
			this.load(args, callback, this.loadSentCallBack);
		},
		
		loadCallBack: function(memberType, args){
			var o = args["rtnValue"] || {}
			o = $.evalJSON(o);
			
			//do received message business here
			var list = o['list'] || [];
			this.pagingList = {}, 
				memberTypeList = memberType == '0' ? this.receivedList : this.sentList;
			for (var i = 0, l = list.length; i < l; i++) {
				var messageItem = new QS.Message.MessageItem(list[i]);
				memberTypeList[messageItem['messageId']] = messageItem;
				this.pagingList[messageItem['messageId']] = messageItem;
			}
			
			//call callback function
			if (typeof(args['callback']) != 'undefined') {
				this.attatchRtnValue(args['callback'],o);
				this.callCallBack(args['callback']);
			}
		},
		loadReceivedCallBack:function(args){
			this.loadCallBack('0',args);
		},
		loadSentCallBack:function(args){
			this.loadCallBack('outbox',args);
		},	
	
		//
		getMessage:function(id, memberType){
			if(memberType == 0){
				return this.receivedList[id];
			}else{
				return this.sentList[id];
			}
		}
	}
});

Class('QS.Message.Intervaler',{
	does:[QS.Message.DBHelper, QS.Message.IComponet],
	has: {
		lastMessageId :{is:'rw',init:'0'},
	    timer:{is:'rw',init:1000 * 60 * 1},
	    intervalerId:{is:'rw',init:false},
	    updateFlag:{is:'rw',init:true}
	},
	
	body:function(){
//		console.log('QS.Message.Intervaler body function invoked.');
	},
	
	methods: {
		initialize: function(){
			var self = this;
			this.intervalerFun();
			this.intervalerId = window.setInterval(function(){
				self.intervalerFun();
			}, this.timer);
		},
		intervalerFun: function(){
			var self = this;
			if (this.updateFlag) {
				this.dataAccess({
					module: 'getUnread',
					messageType: '0',
					lastMessageId: this.lastMessageId
				}, {
					caller: this,
					callee: this.intervalerFunCallBack,
					args: {
						callback: {
							caller: this.getManagement(),
							callee: this.getManagement().loadUreadCallBack,
							args: Joose.I.Object
						}
					}
				});
			}
		},
		intervalerFunCallBack: function(args){
			var o = args["rtnValue"]||{}
			o = $.evalJSON(o);
			if (typeof(o["list"]) != 'undefined') {
				for (var idx = 0, l = o["list"].length; idx < l; idx++) {
					var item = o["list"][idx];
					if (o["list"][idx]["messageId"] > this.lastMessageId) {
						this.lastMessageId = o["list"][idx]["messageId"];
					}
				}
				
				args['callback']["args"]["rtnValue"] = o["list"];
				this.callCallBack(args['callback']);
			}
		}
	}
});

Class('QS.Message.Viewer',{
	does:[QS.Message.IComponet],
	has: {
		cfg			: 	{ is : 'rw', builder : 'buildCfg' },
		HTML 		: 	{ is : 'rw', builder : 'buildHTML' },
		el			: 	{ is : 'rw', builder : 'buildEL' },
		win 		: 	{ is : 'rw', builder : 'buildWin' },
		grid 		:	{ is : 'rw', builder : 'buildGrid' },
		pager 		:	{ is : 'rw', builder : 'buildPager' },
		sortor		:	{ is : 'rw', builder : 'buildSortor' },
		typeMenu	:	{ is : 'rw', builder : 'buildTypeMenu' },
		contentMenu	:	{ is : 'rw', builder : 'buildContentMenu'}
	},
	
	methods: {
		initialize :		function(){
			if (typeof(QS_messageViewer) == 'undefined') {
				QS_messageViewer = this;
			}
			
			this.bindEvent();
			this.resize();
		},
		
		//buider===========================================================
		buildCfg: 			function(){
			return {
				mailType: '0', //0 inbox, 1 outbox
				sortField: '1', // sortField  0:from, 1:received, 2:subject, 3:messageType;
				sortType: '2', //1:asc, 2:desc; default the date will be desc
				show: false,
				width: 768,
				height: 400,
				
				pageSize:20,
				navSize: 5,
				currentSelectRow:0			
			}
		},
		buildHTML:			function(){
			return  '<div class="qs-r qs-message">' +
					    '<div class="qs-c first qs-message-list">' +
						    '<div class="list-hd list-menu asc">' +
							    '<h2><a class="bType" href="javascript:void(0)">Inbox</a></h2>' +
							    '<div class="addnew"><a class="newMessage" href="#">+ New</a></div>' +
							    '<div class="sequence">Newest</div>' +
							    '<div class="sortor" href="javascript:void(0)">' +
							    	'Sort by: <label class="txt">Date</label>' +
					    		'</div>' +
				    		'</div>' +
						    '<div class="list-bd"></div>' +
						    '<div class="list-ft"></div>' +
				    	'</div>' +
					    '<div class="qs-c qs-message-detail">' +
						    '<div class="detail-hd">' +
								'<div class="detail-hd-tl"></div>' +
								'<div class="detail-hd-fr"></div>' +
								'<div class="detail-hd-dt"></div>' +
							'</div>' +
							'<div class="detail-bd"></div>' +
					    '</div>' +
				    '</div>';
		},
		buildEL:			function(){
			return $(this.HTML);
		},
		buildWin: 			function(){
			var self = this;
			var win = new Util.RtqWindow(document.body, {
				windowReady: function(obj){
					self.el.appendTo(obj.contentEl);
				},
				beforeClosed: function(){
					self.close();
					if (QS_MessageSender && typeof QS_MessageSender.hide == 'function') {
						QS_MessageSender.hide();
					}
				},
				onResized: function(obj, w, h){
					self.resize(obj, w, h);
				}
			}, {
				title: 'Message Viewer',
				oldBox: {
					width: self.cfg.width,
					height: self.cfg.height
				},
				width: self.cfg.width,
				minWidth: 668,
				height: self.cfg.height,
				minHeight: 285,
				resizable: true,
				isGlobal: true,
				hasSettingPanel: false,
				closeAction: 'hide'
			});
			
			rtqWindowGroup.register(win);
			if (this.cfg["show"] == false) {
				win.hide();
			}
			return win;
		},
		buildGrid: 			function(){
			var cols = [{header: "rowid", dataIndex: 'rowid', width: 0, dataType: 'string', hide: true}, 
						{header: "received", dataIndex: 'received', width: 0, dataType: 'string', hide: true}, 
						{header: "subject", dataIndex: 'subject', width: 0, dataType: 'string', hide: true}, 
						{header: "type", dataIndex: 'type', width: 0, dataType: 'string', hide: true}, 
						{header: "from", dataIndex: 'from', width: 0, dataType: 'string', hide: true}, 
						{header: "status", dataIndex: 'from', width: 0, dataType: 'string', hide: true}, 
						{header: "content", dataIndex: "content", width: "70%", dataType: 'html'}, 
						{header: "dtime", dataIndex: "dtime", width: "25%", dataType: 'html'}, 
						{header: 'DEL', dataIndex: 'remove', type: 'remove', renderer: '<a href="javascript:;">Remove</a>', width: "5%", confirm: true}];
			
			var config = {
				column: cols,
				ath: true,
				height: (this.cfg.height - 46),
				autoWidth: true,
				outSideHeader: true,
				htmlLayer: 'div',
				confirm: true,
				rowDragDropGroup: 'GRID1'
			};
			var self = this;
			var callback = {
				onRowSelected: function(e, row){
					var id = row["data"]["rowid"];
					row.el.css({'font-weight': 'normal'});
					self.getManagement().read(id);
					self.cfg.currentSelectRow=row["data"]["rowIndex"];
				},
				onRowRemove: function(id, row){
					self.getManagement().remove(id);
				},
				onRowContextmenu: function(e, row){
					if (self.cfg.mailType == '1') 
						return;
						
					self._selectRow(row["data"]["rowIndex"]);
					var msg = self.getManagement().getMessage(row.id, '0');
					self.rebindMenuData(msg);
					self.showContentMenu(e);
				},
				onRowDoubleClick: function(e, row){
					self._selectRow(row["data"]["rowIndex"]);
				
					var id = row["data"]["rowid"];
					row.el.css({'font-weight': 'normal'});
					self.getManagement().read(id,'1');
				}
			}
			var grid = new Util.DataGrid(this.el.find(".qs-message-list .list-bd"), [], config, callback);
			grid.header.el.hide();
			return grid;
		},
		buildPager: 		function(){
			var self = this;
			return new Util.PageUtil(this.el.find('.list-ft'), {
				onClick: function(start, end){
					var pageNo = Math.ceil(start / self.cfg.pageSize);
					self.jumpToPage(pageNo);
				}
			}, {
				navSize: self.cfg.navSize,
				pageSize: self.cfg.pageSize,
				total: QS_MsgTotalReceivedNum
			});
		},
		buildSortor:		function(){
			var self = this;
	        var sortEl = this.el.find(".qs-message-list .list-hd .sortor");
	        var sortor = new Util.CascadeMenu(sortEl, {
	            display: false,
	            isTraceMouse: true,
	            autoHide: true,
	            fixedDirection: false
	        }, [{txt: "From",val: "0"}, 
							{txt: "Date",val: "1"}, 
							{txt: "Subject",val: "2"}, 
							{txt: "Type",val: "3"}], {
	            onClick: function(item){
					if(self.cfg.sortField == item.data.val){
						sortor.hide();
						return;
					}
					self.cfg.sortField = item.data.val;
					var d = {
			            "0": "A to Z",
			            "1": "Newest",
			            "2": "A to Z",
			            "3": "A to Z"
			        };
					self.el.find('.list-hd .sequence').html(d[item.data.val]);
					self.el.find('.list-hd .sortor .txt').html(item.data.txt);
					if (self.cfg.sortField == '1') {
						self.cfg.sortType = '2';
					}else {
						self.cfg.sortType = '1';
					}
	                self.jumpToPage(1);
					self.rebindPagingConfig();
	            }
	        });
	        sortor.hide();
	        sortEl.find(".txt").bind("click", function(){
	            self.sortor.show();
	        });
        	return sortor;
		},
		buildTypeMenu:		function(){
			var self = this;
			var $typeMenuContainer = this.el.find('.list-hd h2:first');
			var typeMenu = new Util.CascadeMenu($typeMenuContainer, {
				display: true,
				isTraceMouse: true,
				autoHide: true,
				fixedDirection: false
			}, [{
				txt: "Inbox",
				val: "0"
			}, {
				txt: "Outbox",
				val: "1"
			}], {
				onClick: function(item){
					if (self.cfg.mailType != item.data.val) {
						self.cfg.mailType = item.data.val;
						self.el.find('.list-hd .bType').html(self.cfg.mailType == '0' ? 'Inbox' : 'Outbox');
						//self.cfg.sortField = '1';
						//self.cfg.sortType = '2';
						self.jumpToPage(1);
						typeMenu.hide();
						self.rebindPagingConfig();
					}else{
						typeMenu.hide();
					}
				}
			});
			$typeMenuContainer.bind('click', function(e){
				typeMenu.show();
			});
			return typeMenu;
		},
		buildContentMenu: 	function(){
			var self = this;
			var contentMenu = new Util.CascadeMenu($('body'), {
				display: true,
				isTraceMouse: true,
				autoHide: true,
				fixedDirection: false
			}, this._getContenMenuData(), {
				onClick: function(item){
					var msgId = item.data.id;
					switch (item.data.val) {
						case 'open in curent':
						case 'open in new':
							var msg = self.getManagement().getMessage(msgId,'0');
							if (typeof(QS_ShareModule) == 'undefined' || QS_ShareModule == null) {
								QS_ShareModule = new ShareModule();
							}
							var msgType=self.getManagement().getMessageType(msg);
							if(msgType=="SHARE-WS"){
								QS_ShareModule.openShared(msg, false);
							}else if(msgType=="SHARE-WG"){
								QS_ShareModule.openShared(msg, item.data.val == 'open in curent' ? true : false);
							}
							
							break;
						case 'reply':
							self.readMsg(msgId, "0", function(msg){
								self.grid.rows[msgId].el.css({'font-weight': 'normal'});
									if (QS_MessageSender == null) {
										QS_MessageSender = new MessageSender();
									}
									QS_MessageSender.open("message", null, null, msg);
								});
							break;
						case 'read':
							self.grid.rows[msgId].el.css({
								'font-weight': 'normal'
							});
							self.readMsg(msgId);
							break;
						case 'delete':
							Util.confirm("Are you sure want to delete?", function(b){
								if (b == true) {
									self.grid.removeRow(msgId);// remove from grid
									self.getManagement().remove(msgId);// remove from database
								}
							});
							break;
					}
				}
			});
			return contentMenu;
		},
		//==================================================================
		
		bindEvent: function(){
			var self = this;
			this.el.find('.addnew').bind('click', function(e){
				e.preventDefault();
				if (QS_MessageSender == null) {
					QS_MessageSender = new MessageSender();
				}
				QS_MessageSender.open("message");
				return false;
			});
			this.el.find('.list-hd .sequence').bind('click', function(){
				var dom = $(this);
				if (dom.parent().hasClass("asc")) {
					dom.parent().removeClass("asc").addClass("desc");
					self.cfg.sortType = '2';
					self.jumpToPage(self.pager.curPage);
				}
				else {
					dom.parent().removeClass("desc").addClass("asc");
					self.cfg.sortType = '1';
					self.jumpToPage(self.pager.curPage);
				}
			});
		},
		
		//content menu=======================================================
		showContentMenu: function(e){
	       // var top = e.clientY - this.win.cfg.top - 40 + this.grid.scrollPanel.scrollTop; //- this.win.cfg.top - 40;
	        this.contentMenu.menu.css({
	            "left": e.pageX,
	            "top":  e.pageY
	        });
	        this.contentMenu.show();
	    },
	    _getContenMenuData: function(msg){
			msg = msg||{};
	        var data = [{txt: "Read", val: "read", id: msg['messageId']}];
			switch (msg['messageType']) {
				case 0:
					data.push({txt: "Reply",val: "reply", id: msg['messageId']});
					break;
				case 1:
				 	data.push({txt: "Reply",val: "reply", id: msg['messageId']});
					if (typeof(msg['attachment']) != 'undefined' && msg['attachment'].indexOf(',') != -1) {
						var attachment = msg['attachment'].split(',');
						if(attachment[1] && attachment[1] == '0'){
							data.push({txt: "Open",val: "open in new", id: msg['messageId']});
						}else{
							data.push({txt: "Open in new workspace",val: "open in new", id: msg['messageId']});
							data.push({txt: "Open in curent workspace",val: "open in curent", id: msg['messageId']});
						}
					}
					break;
				case 2:
				case 3:
					break;
			}
			data.push({txt:"Delete", val: "delete", id: msg['messageId']});
	        return data;
	    },
	    rebindMenuData: function(msg){
	        var data = this._getContenMenuData(msg);
	        this.contentMenu.reBind(data);
	    },
		//===================================================================
		
		//paging=============================================================
		reLoadMSGList:function(){
			this.jumpToPage(this.pager.curPage);
		},
		jumpToPage: function(pageNo){
			var param = {
				mailType: this.cfg.mailType, //0 inbox, 1 outbox
				pageSize: this.pager.config['pageSize'],
				pageNo: pageNo,
				sortField: this.cfg.sortField, // sortField  0:from, 1:received, 2:subject, 3:messageType;
				sortType: this.cfg.sortType //1:asc, 2:desc
			}
			
			this.getManagement().load(param);
		},
		rebindPagingConfig: function(){
			//QS_MsgTotalReceivedNum,QS_MsgTotalSentNum
			var total = this.cfg.mailType == 0 ? QS_MsgTotalReceivedNum : QS_MsgTotalSentNum;
			var config = {
				total: total,
				curPage: 1
			};
			this.pager.rebind(config);
		},
		//===================================================================
		
		//Grid===============================================================
		bindGridData: function(list){
			if(typeof(list)=='undefined'||!list.length){
				this.grid.reBindData([]);
            	this.emptyDetailPannel();
            	this.grid.el.find('.rtq-grid-bd').append('<div class="nodata" style="text-align: center;">There are no items with this label.</div>');
				return ;
			}
			var data = [], typeMap = this.getManagement().typeMap;;
			for (var i=0; i<list.length; i++) {
				var d = {};
				var item = list[i];
				d["rowid"] = item['messageId'];
				d["content"] = this._formateMessageContent(item);
				d["dtime"] = item["createTime"];
				d["status"] = item["messageStatus"];
				d["received"] = item["createTime"];
				d["subject"] = item["subject"];
				d["type"] = typeMap[item["messageType"]];
				d["from"] = (this.cfg.mailType == '0' ? item["senderAddress"] : item["receiverAddress"]);
				d["rowIndex"]=i;
				data.push(d);
			}
			this.grid.reBindData(data);
			
			//mark out unread emails when open inbox
			if(this.cfg.mailType == '0'){
				for (var p in this.grid.rows) {
	                var row = this.grid.rows[p];
	                if (row.data.status == '0') {
	                    row.el.css({ "font-weight": "bold" });
	                }
	            }
			}
			
			this._selectRow(this.cfg.currentSelectRow);

		},
		
		_selectRow:function(rowIndex){
			this.cfg.currentSelectRow=rowIndex;
			var rowId = this.grid.body.find('.rtq-grid-row').eq(rowIndex).attr('rowid');
			this.grid.selectRow(rowId);
		},
		_formateMessageContent: function(item){
//			var typeMap = this.getManagement().typeMap;
			var type = item["messageType"]; content = '';
			var subjectStr=this.getManagement().getMessageSubjectString(item);
			
			content = '<div class="address">' + (type == 2 || type == 3 ? "Morningstar Quotespeed" : item["senderAddress"]) + '</div>'+
					  '<div class="subject">' + subjectStr + ':' +item["subject"] + '</div>';
			return content;
		},
		emptyDetailPannel: function(){
	        var mContainer = this.detailPanelDiv;
	        if (mContainer) {
	            mContainer.find(".detail-hd-tl").html('');
	            mContainer.find(".detail-hd-fr").html('');
	            mContainer.find(".detail-hd-dt").html('');
	            mContainer.find(".detail-bd").html('');
	        }
	    },
		//===================================================================
		
		//read MSG===========================================================
		readMsg:function(messageId, openType, callback){
			this.getManagement().read(messageId, openType, callback);
			
		},
		readMsgCallBack: function(message){
	        if (!this.detailPanelDiv) {
	            this.detailPanelDiv = this.el.find(".qs-message-detail");
	            this.detailPanel = new Util.ScrollPanel(this.detailPanelDiv.find(".detail-bd"));
	        }
	        		
	        var mContainer = this.detailPanelDiv;
	        var dType = message["messageType"];//, typeMap = this.getManagement().typeMap;
			
			//add open button.
			if(!mContainer.find(".detail-hd-open").length){
				mContainer.find(".detail-hd").prepend('<div class="detail-hd-open" style="float:right;overflow:show;">'+
														'<span class="qs-ui-btn open-btn" style="float:right;">open<span></span></span>'+
														'<div class="open-menu" style="clear:both;"></div>'+
													  '</div>');
				var self=this;
				var openMenu = new Util.CascadeMenu(mContainer.find(".detail-hd-open .open-menu"), {
					display: false,
					isTraceMouse: true,
					autoHide: true,
					fixedDirection: true
				}, [{
					txt: 'In Current Workspace',
					val: 'current'
				}, {
					txt: 'In New Workspace',
					val: 'new'
				}], {
					onClick: function(item){

						var msg=self.currentMsg;
						QS_ShareModule.openShared(msg, item.data.val == 'open in curent' ? true : false);
						
					}
				});
				
				var $openBtn=mContainer.find(".detail-hd-open .open-btn");
				var offset=$openBtn.offset();
				offset.left-=85;
				mContainer.find(".detail-hd-open .open-menu").offset(offset);
				
				$openBtn.bind("click",function(e){
					var msg=$(this).data("msg");
					if (typeof(QS_ShareModule) == 'undefined' || QS_ShareModule == null) {
							QS_ShareModule = new ShareModule();
					}
					var msgType=self.getManagement().getMessageType(msg);
					if(msgType=="SHARE-WS"){
						QS_ShareModule.openShared(msg, false);
					}else if(msgType=="SHARE-WG"){//widget
						self.currentMsg=msg;
						openMenu.show();
					}

				});
			}

			
			if(dType==1){
						
				//bind message to dom.
				mContainer.find(".detail-hd-open .open-btn").data("msg",message);
				var msgType=this.getManagement().getMessageType(message);
				if(msgType=="SHARE-WS"){
					mContainer.find(".detail-hd-open .open-btn span").removeClass("qs-sharing-btn-suffix");
				}else if(msgType=="SHARE-WG"){
					mContainer.find(".detail-hd-open .open-btn span").addClass("qs-sharing-btn-suffix");
				}
				mContainer.find(".detail-hd-open .open-btn").show();
			}else{
				mContainer.find(".detail-hd-open .open-btn").hide();
			}
			
			var subjectStr=this.getManagement().getMessageSubjectString(message);
	        mContainer.find(".detail-hd-tl").html("<strong>" + subjectStr + ":</strong>" + message["subject"]);
	        mContainer.find(".detail-hd-fr").html("<strong>" + (this.cfg.mailType == '0' ? 'From' : 'To') + ":</strong>" + (dType == 2 || dType == 3 ? "Morningstar Quotespeed" : message[this.cfg.mailType == '0' ? "senderAddress" : "receiverAddress"]));
	        mContainer.find(".detail-hd-dt").html("<strong>Date:</strong>" + message['createTime']);
	        var temp = dType == 2 ? message['content'] : "<pre style='white-space:pre-wrap;white-space:-moz-pre-wrap;white-space:-pre-wrap;white-space:-o-pre-wrap;word-wrap:break-word;'>" + message['content'] + "</pre>";
	        mContainer.find(".detail-bd").html(temp);
	        this.resize();
	    },
		//===================================================================
		//UI=================================================================
		open: function(){
			if (!this.cfg.show) {
				this.cfg.show = true;
				this.win.show();
				this.resize();
			}
		},
		close:function(){
			this.cfg.show = false;
		},
		resize: function(obj, w, h){
			if(!this.cfg.show)return; // if view is close, no need to resize
			var container = this.el.parent();
			w = container.width();
			h = container.height();
			var detailTitleHeight = this.el.find(".qs-message-detail .detail-hd").height() + 18;
			this.grid.resize('100%', h - 51);//header:26px, footer:25px
			this.el.find('.list-bd').css({
				'height': h - 51
			});//header:26px, footer:25px
			if (this.detailPanel) {
				this.detailPanel.reSize('100%', h - detailTitleHeight);
			}
		}
		//===================================================================
	}
});

Class('QS.Message.Notifier',{
	does:[QS.Message.IComponet],
	has: {
		cfg			: 	{ is : 'rw', builder : 'buildCfg' },
		HTML 		: 	{ is : 'rw', builder : 'buildHTML' },
		el			: 	{ is : 'rw', builder : 'buildEL' },
		win 		: 	{ is : 'rw', builder : 'buildWin' },
		currentIdx 	:	{ is : 'rw', builder : 'buildCurrentIdx' },
		msgs 		:	{ is : 'rw', builder : 'buildMsgs' },
		openMenu	: 	{ is : 'rw', builder : 'buildOpenMenu'}
	},
	methods: {
		initialize: function(){
			this._bindEvent();
		},
		
		//builder=============================================================
		buildCfg: function(){
			return {};
		},
		buildHTML: function(){
			return '<div class="message-notifier">' +
			    '<div class="hd">' +
				    '<h3 class="title">New Message:0/0</h3>' +
				    '<a href="#" class="previous"></a>' +
				    '<a href="#" class="next"></a>' +
			    '</div>' +
			    '<div class="bd">' +
				    '<div class="m-title"></div>' +
				    '<div class="m-subject"></div>' +
			    '</div>' +
			    '<div class="ft">' +
				    '<a href="javascript:void(0)" class="qs-ui-btn">Delete</a>' +
					'<a href="javascript:void(0)" class="qs-ui-btn">Open<span></span></a>' +
			    '</div>' +
		    '</div>';
		},
		buildEL: function(){
			return $(this.HTML);
		},
		buildWin: function(){
			var self = this;
			var win = new Util.RtqWindow(document.body, {
	            windowReady: function(obj){
	                self.el.appendTo(obj.contentEl);
	            },
	            beforeClosed: function(){
	            },
	            onResized: function(){
	            }
	        }, {
	            title: 'Message Notifier',
	            width: 250,
	            minWidth: 250,
	            height: 130,
	            minHeight: 130,
	            resizable: false,
	            isGlobal: true,
	            hasSettingPanel: false,
	            closeAction: 'hide',
	            hasSettingPanel: false
	        });
        	rtqWindowGroup.register(win);
			win.hide();
/*			win.hide = function(){
				var self=this;
                var top = -140, left = $(window).width() - 250;
                this.el.animate({
                    top: top,
                    left: left
                }, 200,function(){self.el.hide();});
                if (this.active) {
                    rtqWindowGroup.shadow.shadowEl.animate({
                        top: top,
                        left: left
                    }, 200);
                }
            };*/
			return win;
		},
		buildCurrentIdx: function(){
			return null;
		},
		buildMsgs: function(){
			return null;
		},
		buildOpenMenu:function(){
			var self = this;
			var openMenu = new Util.CascadeMenu(this.win.el.find(".rtq-win-tools"), {
				display: false,
				isTraceMouse: true,
				autoHide: true,
				fixedDirection: true
			}, [{
				txt: 'In Current Workspace',
				val: 'current'
			}, {
				txt: 'In New Workspace',
				val: 'new'
			}], {
				onClick: function(item){
				
					var msg=self.currentMsg;
					self.getManagement().readSharing(msg["messageId"], item.data.val);
//					QS_ShareModule.openShared(msg, item.data.val == 'current' ? true : false);
					self.toNextMsg(msg);
				}
				
			});
			openMenu.setPosition(100, 127);
			return openMenu;
		},
		//====================================================================
		
		_bindEvent: function(){
			var self = this;
			this.el.find(".qs-ui-btn:contains('Open')").bind("click", function(){
				var msg = self.msgs[self.currentIdx - 1];
				if (msg["messageType"] == '1') {
					self._openOpenMenu(msg);
				}
				else {
					self.getManagement().read(msg["messageId"], '1');
					self.toNextMsg(msg);
				}
			});
			this.el.find(".qs-ui-btn:contains('Delete')").bind("click", function(){
				Util.confirm("Are you sure want to delete?", function(b){
					if (b == true) {
						self.getManagement().remove(self.msgs[self.currentIdx - 1]["messageId"]);
					}
				});
			});
			this.el.find(".hd .next").bind("click", function(){
				self.next();
			});
			this.el.find(".hd .previous").bind("click", function(){
				self.previous();
			});
			
			/////////////////////////////////////////////////////////////////////////////
			var timer = window.setTimeout(function(){self.slideUp();}, 40*1000);
			this.el.hover(function(){
				window.clearTimeout(timer);
			},function(){
				timer = window.setTimeout(function(){self.slideUp();}, 40*1000);
			});
			/////////////////////////////////////////////////////////////////////////////
		},
		deleteCallBack: function(args){
			var msg = args['msg'];
			if (msg.memberType == '0'&&this.msgs) {
				var msg = args['msg'];
				for (var i = 0; i < this.msgs.length; i++) {
					if (this.msgs[i]["messageId"] == msg["messageId"]) {
						this.msgs.splice(i, 1);
						
						if (this.currentIdx == i + 1) {
							this._showMsgByIdx(i + 1);
							if(this.msgs.length == 0){
								this.slideUp();
							}
						}
						else {
							var elHtml = this.el.find(".hd .title").html();
							if (this.currentIdx != this.msgs.length) {
								elHtml = elHtml.replace(/[\d]+$/, this.msgs.length);
							}
							else {
								elHtml = elHtml.replace(/[\d]+\/[\d]+$/, this.msgs.length + '/' + this.msgs.length);
							}
							
							this.el.find(".hd .title").html(elHtml);
						}
					}
				}
			}
		},
		popUpAndShowNewMsg: function(list){
			if (list.length) {
				this.currentIdx = 1;
				this.msgs = list;
			}
			this.slideDown();
		},
		next: function(){
			this.currentIdx == this.msgs.length ? (this.currentIdx = 1) : this.currentIdx++;
			this._showMsgByIdx();
		},
		previous: function(){
			this.currentIdx == 1 ? (this.currentIdx = this.msgs.length) : this.currentIdx--;
			this._showMsgByIdx();
		},
		toNextMsg: function(msg){
			for(var i=0;i<this.msgs.length;i++){
				if(this.msgs[i].messageId==msg.messageId){
					this.msgs.splice(i,1);
				}
			}
			if(!this.msgs.length){
				this.slideUp();
			}else{
				this._showMsgByIdx();
			}
		},
		
		_showMsgByIdx: function(idx){
			idx = idx || this.currentIdx;
			if (this.msgs.length != 0) {
//				var typeMap = this.getManagement().typeMap;
				this.el.find(".hd .title").html("New Message:" + idx + "/" + this.msgs.length);
				var msg = this.msgs[idx - 1];
				this.el.find(".bd .m-title").html(msg["senderAddress"]).ellipsis(true);
				
				var subjectStr=this.getManagement().getMessageSubjectString(msg);
				this.el.find(".bd .m-subject").html("<strong>" + subjectStr + ": </strong>" + msg["subject"]).ellipsis(true,0);
				
//				var msg=this.getManagement().getMessage(msg.messageId,0);//0 for recv list.
				var msgType=this.getManagement().getMessageType(msg);
				if(msgType=="SHARE-WG"){
					this.el.find(".qs-ui-btn:contains('Open') span").addClass("qs-sharing-btn-suffix");
				}

				
			}else {
				this.el.find(".hd .title").html("New Message:0/0");
				this.el.find(".bd .m-title").html("No new received messages");
				this.el.find(".bd .m-subject").html("");
			}
		},
		
		show: function(){
			if (this.currentIdx) {
				this._showMsgByIdx(this.currentIdx);
			}
			this.win.show();//this.win.el.show();
		},
		close: function(){
			this.win.setLock(false);
			var self=this;
			var top = -140, left = $(window).width() - 250;
			this.el.animate({
				top: top,
				left: left
			}, 200, function(){self.win.hide();});
			
			if (this.active) {
				rtqWindowGroup.shadow.shadowEl.animate({
					top: top,
					left: left
				}, 200);
			}
		},
		slideUp: function(){
			this.win.setLock(false);
			this.close();
		},
		slideDown: function(){
			var top = -140, left = $(window).width() - 250;
			this.win.setPosition(left, top);
			this.show();
			this.win.el.animate({
				top: 60
			}, 1000);
			rtqWindowGroup.active(this.win);
			this.win.setLock(true, true);
		},
		
		open: function(type, id, inCurrentSpace){//open share
			id = id || this.currentID;
			if (id) {
				var sType = QS_ShareModule.getTypeById(id);
				if (sType != "sType") {
					QS_ShareModule.openSharedWorkspace(id);
				}
				else {
					QS_ShareModule.openSharedWigdets(id);
				}
			}
		},
		_openOpenMenu: function(msg){
/*			var data = [];
			if (typeof(msg['attachment']) != 'undefined' && msg['attachment'].indexOf(',') != -1) {
				var attachment = msg['attachment'].split(',');
				if(attachment[1] && attachment[1] == '1'){
					data.push({txt: 'In Current Workspace', val: 'current', id: msg["messageId"]});
				}
			}
			data.push({txt: 'In New Workspace', val: 'current', id: msg["messageId"]});
	        this.openMenu.reBind(data);*/
//			var msg=this.getManagement().getMessage(msg.messageId,0);//0 for recv list.

			var msgType=this.getManagement().getMessageType(msg);
			if(msgType=="SHARE-WS"){
				this.getManagement().readSharing(msg["messageId"],"current");
//				QS_ShareModule.openShared(msg, false);
				this.toNextMsg(msg);
			}else if(msgType=="SHARE-WG"){//widget
				this.currentMsg=msg;
				this.openMenu.setPosition(100, 127);
				this.openMenu.show();
			}

		}
	}
});

Class('QS.Message.Management',{
	has: {
		typeMap : 	{is:'rw',init:{0: 'Mail', 1: 'Sharing', 2: 'Data Alert', 3: 'System Notification'}},
		unReadNum:	{is:'rw',init:0},
		totalRec:	{is:'rw',init:0},
		totalSnt:	{is:'rw',init:0},
		
		maxMailSize:					{is:'rw',init:200},
		ninetyPercentSize:				{is:'rw',init:function(){this.maxMailSize * 0.9}},
		mailboxFullStatus:				{is:'rw',init:false},
		ninetyPercentFullStatus:		{is:'rw',init:false},
		ignoreNinetyPercentFullStatus:	{is:'rw',init:false},
		
		dataManager:{is:'rw',builder:'buildDataManager'},
		intervaler:	{is:'rw',builder:'buildIntervaler'},
		viewer:		{is:'rw',builder:'buildViewer'},
		notifier:	{is:'rw',builder:'buildNotifier'}
	},
	
	methods: {
		//builder=============================================================
		buildDataManager:function(){
			return new QS.Message.DataManager({
				management: this
			});
		},
		buildIntervaler: function(){
			return new QS.Message.Intervaler({
				management: this
			});
		},
		buildViewer: function(){
			return new QS.Message.Viewer({
				management: this
			});
		},
		buildNotifier: function(){
			return new QS.Message.Notifier({
				management: this
			});
		},
		//====================================================================
		
		//load message========================================================
		load:function(args){
			var Fun = args['mailType'] == '0'?
				this.dataManager.loadReceived : this.dataManager.loadSent;
			Fun.apply(this.dataManager,[args,{
				caller: this,
				callee: this.loadListCallBack,
				args: args
			}]);
		},
		loadListCallBack:function(args){
			//viewer needs rebind grid data and paging config 
			var list = args["rtnValue"]["list"];
			//this.viewer.rebindPagingConfig(args);
			this.viewer.bindGridData(list);
			this.viewer.resize();
		},
		loadUreadCallBack:function(args){
			var list = args["rtnValue"];
			
			//notifier needs pop up, unread message number need to be updated
			if(list.length){
				this.unReadNum += list.length;
				this.updateUnreadDom();
				this.notifier.popUpAndShowNewMsg(list);	
			}
			
			//the viewer list should be refreshed when sorted by received and pageNo. is 1.
			var viewerCfg = this.viewer.cfg;
			if (viewerCfg.mailType == '0' && viewerCfg.sortField == '1') {
				this.viewer.reLoadMSGList();
			}
		},
		
		updateUnreadDom: function(){
			if (!this.el) {
				this.el = $('.qs-message-note');
			}
			this.el.find('span').html(this.unReadNum == 0? "" : this.unReadNum);
		},
		//====================================================================
		
		read:function(msgId, openType, callback){
			openType = openType || '0';//0: open in viewer, 1: open in single window
			var item = this.dataManager.pagingList[msgId];
			if(typeof(item)=='undefined'){
				item = new QS.Message.MessageItem({messageId:msgId, messageStatus:'0',memberType:"0"});
			}
			if (item['messageStatus'] == '0' || typeof(item['content']) == 'undefined' || item['content'] == undefined) {
				item.read({caller: this, callee: this.readCallBack, args: {openType: openType, callback: callback}});
				if (item['messageStatus'] == '0' && item['memberType'] == '0') {
					if(this.unReadNum <=0){return;}
					this.unReadNum -= 1;
					this.updateUnreadDom();
				}
			} else {
				this.readCallBack({openType: openType, callback: callback, rtnValue: item});
			}
		},
		readCallBack:function(args){
			var item = args['rtnValue'];
			var openType=args["openType"];
			var callback=args["callback"];
/*			if(openType == '0'){
				this.viewer.readMsgCallBack(item);
			}else if(openType == '1'){
				item.my.openInNewWindow(item);
			}
*/			

			if(openType == '0'){
				this.viewer.readMsgCallBack(item);
			}else if(openType == '1'){
				item.my.openInNewWindow(item);
			}
			
			//call other callback
			callback&&callback(item);
		},
		
		readSharing:function(msgId, openType){
			var item = this.dataManager.pagingList[msgId];
			if(typeof(item)=='undefined'){
				item = new QS.Message.MessageItem({messageId:msgId, messageStatus:'0',memberType:"0"});
			}

			item.read({caller: this, callee: this.readSharingCallback, args: {openType: openType}});
			if (item['messageStatus'] == '0' && item['memberType'] == '0') {
				if(this.unReadNum <=0){return;}
				this.unReadNum--;
				this.updateUnreadDom();
			}
		
		},
		
		readSharingCallback:function(args){
			var item = args['rtnValue'];
			var openType=args["openType"];
			var msgType=this.getMessageType(item);
			if(msgType=="SHARE-WG"){
				QS_ShareModule.openShared(item, openType == 'current' ? true : false);				
			}else if(msgType=="SHARE-WS"){
				QS_ShareModule.openShared(item, false);
			}
		},
		
		remove:function(msgId,args){
			var item = this.dataManager.pagingList[msgId]
				||new QS.Message.MessageItem({messageId:msgId, messageStatus:'0',memberType:"0"});//from notifier
			item.remove({caller: this, callee: this.removeCallBack, args: {}});
		},
		removeCallBack:function(args){
//			console.log(args);
			var item = args['rtnValue'];
			if (typeof(item)!='undefined' && typeof(item['messageId'])!='undefined') {
				Util.message('Delete success!');
				//update viewer list
				var itemId = item['messageId'];
				if(this.dataManager.pagingList[itemId]){
					this.viewer.reLoadMSGList();
				}
				
				
				
				//update notifier list
				args['msg'] = item;
				this.notifier.deleteCallBack(args);
				
				//update unReadNum
				if(item.memberType == "0" && item.messageStatus == "0"){
					this.unReadNum -= 1;
					this.updateUnreadDom();
				}
			}
		},
	
		//interface===========================================================
		getMessage:function(id, memberType){
			return this.dataManager.getMessage(id, memberType);
		},
		
		getMessageType:function(msg){
			var msgType=msg["messageType"];

			if(msgType==0){
				return "MAIL";
			}else if(msgType==1){
				
				if (typeof(msg['attachment']) != 'undefined' && msg['attachment'].indexOf(',') != -1) {
					var attachment = msg['attachment'].split(',');
					if (attachment[1] && attachment[1] == '0') {
						//workspace
						return "SHARE-WS"
					}else {
						//widget
						return "SHARE-WG";
					}
				}
			}
			return "UNKOWN";
		},
		
		getMessageSubjectString:function(msg){		
			var suffix="";
			var msgType=this.getMessageType(msg);
			if(msgType=="SHARE-WG"){
				if(this.el){
					this.el.find(".qs-ui-btn:contains('Open') span").addClass("qs-sharing-btn-suffix");
				}
				suffix=" widget";
			}else if(msgType=="SHARE-WS"){
				suffix=" workspace";
			}
			
			return this.typeMap[msg["messageType"]] + suffix;
		}
	}
});

QS_MessageManagement = new QS.Message.Management();

$(document).ready(function(){
	QS_ShareModule = new ShareModule();
})
